<?php


namespace app\api\controller\v2;

use app\common\controller\JwtTools;
use think\exception\HttpResponseException;
use think\Request;
use think\Response;

class Base
{
    protected $params;
    /**
     * @var Request Request 实例
     */
    protected $request;
    /**
     * 默认响应输出类型,支持json/xml
     * @var string
     */
    protected $responseType = 'json';
    /**
     * 未登录状态码
     * @var string
     */
    protected $loginErorCode = 302;

    /**
     * 不需要登录的控制器方法
     * @var array
     */
    protected $dontNeedTokenApi = [
        '/api/v2/index/index',
    ];


    /**
     * 构造方法
     * @access public
     * @param Request $request Request 对象
     */
    public function __construct(Request $request = null)
    {
        $this->request = $request ?? Request::instance();

        // 控制器初始化
        $this->init();

        $this->params = $this->request->param();
    }

    protected function init()
    {
        //跨域请求检测
//        check_cors_request();
        //移除HTML标签
        $this->request->filter('trim,strip_tags,htmlspecialchars');

        $header = $this->request->header();

        $this->request->user_id = null; // 初始化user_id属性为null

        if (!empty($header['access_token'])) {
            $jwt = new JwtTools();
            $res = $jwt->de_token($header['access_token']);

            if ($res['code'] == 'success' && isset($res['data']['data']))
            {
                $userData = $res['data']['data'];
                if (is_object($userData) && property_exists($userData, 'user_id')) {
                    $this->request->user_id = $userData->user_id;
                } elseif (is_array($userData) && array_key_exists('user_id', $userData)) {
                    $this->request->user_id = $userData['user_id'];
                }
            } else {
                $this->error($res['data']);
            }
        }

        $this->checkLogin();

    }


    /**
     * 操作成功返回的数据
     * @param string $msg 提示信息
     * @param mixed $data 要返回的数据
     * @param int $code 错误码，默认为1
     * @param string $type 输出类型
     * @param array $header 发送的 Header 信息
     */
    protected function success($msg = '', $data = null, $code = 1, $type = null, array $header = [])
    {
        $this->result($msg, $data, $code, $type, $header);
    }

    /**
     * 操作失败返回的数据
     * @param string $msg 提示信息
     * @param mixed $data 要返回的数据
     * @param int $code 错误码，默认为0
     * @param string $type 输出类型
     * @param array $header 发送的 Header 信息
     */
    protected function error($msg = '', $data = null, $code = 0, $type = null, array $header = [])
    {
        $this->result($msg, $data, $code, $type, $header);
    }

    /**
     * 返回封装后的 API 数据到客户端
     * @access protected
     * @param mixed $msg 提示信息
     * @param mixed $data 要返回的数据
     * @param int $code 错误码，默认为0
     * @param string $type 输出类型，支持json/xml/jsonp
     * @param array $header 发送的 Header 信息
     * @return void
     * @throws HttpResponseException
     */
    protected function result($msg, $data = null, $code = 0, $type = null, array $header = [])
    {
        $result = [
            'code' => $code,
            'msg' => $msg,
            'time' => Request::instance()->server('REQUEST_TIME'),
            'data' => $data,
        ];
        // 如果未设置类型则自动判断
        $type = $type ? $type : ($this->request->param(config('var_jsonp_handler')) ? 'jsonp' : $this->responseType);

        if (isset($header['statuscode'])) {
            $code = $header['statuscode'];
            unset($header['statuscode']);
        } else {
            //未设置状态码,根据code值判断
            $code = $code >= 1000 || $code < 200 ? 200 : $code;
        }
        $response = Response::create($result, $type, $code)->header($header);
        throw new HttpResponseException($response);
    }

    /**
     * 验证是否需要登录
     * @access protected
     * @return bool
     */
    public function checkLogin()
    {
        if (in_array(request()->url(), $this->dontNeedTokenApi)) {
            return true;
        }
        if (empty($this->request->user_id)) {
            $this->result('请先登录', null, $this->loginErorCode);
        }

        return true;
    }
}